S00-00 General-Cloudflare-项目:115网盘
[TOC]
项目:115网盘
本章将整合前几章学习的 Pages (前端托管)、Functions (后端逻辑) 和 Wrangler (本地开发) 知识,构建一个完整的全栈应用——“115 网盘本地化管理工具”。
这个项目的核心痛点是:115 网盘的 API 有严格的 Cookie 校验和防盗链机制,前端无法直接在浏览器中调用(会报跨域 CORS 错误)。我们需要利用 Cloudflare Pages Functions 作为“中间人”来转发请求。
115 网盘实战架构
核心逻辑
该项目的架构设计如下:
- 前端 (Vue 3): 负责界面交互(如展示文件列表、重命名按钮、删除按钮)。
- 后端 (Pages Functions): 运行在 Cloudflare 边缘,负责中转请求。它会读取环境变量中的 Cookie,伪造请求头欺骗 115 服务器,并将结果返回给前端。
- 本地环境: 使用 Wrangler 模拟 Cloudflare 生产环境,代理 Vite 服务器。
项目初始化与结构
首先创建一个标准的 Vue 项目,然后在根目录下建立 Cloudflare Pages 特有的目录结构。
my-115-project/
├── .dev.vars # 本地敏感变量 (存放 Cookie)
├── package.json # 项目依赖与脚本
├── wrangler.toml # 资源绑定配置
├── src/ # Vue 前端代码
│ └── App.vue
└── functions/ # 后端 API 代码 (约定路由)
└── api/
├── 115.js # -> 映射为 /api/115 接口
└── img-proxy.js # -> 映射为 /api/img-proxy 接口接口与鉴权 (通用中转)
我们需要编写一个通用的 API 接口,用于接收前端传来的目标 URL,并附带上 Cookie 转发给 115。
后端代码实现
请在 functions/api/115.js 中写入以下代码:
export async function onRequest(context) {
// 1. 从环境变量中获取 Cookie
// 在本地,它读取 .dev.vars;在线上,它读取 Cloudflare 后台配置的 Secrets
const COOKIE = context.env.COOKIE_115
if (!COOKIE) {
return new Response(JSON.stringify({ state: false, error: '未配置 Cookie' }), {
headers: { 'Content-Type': 'application/json' }
})
}
// 2. 获取前端传来的参数 (Target URL)
const url = new URL(context.request.url)
const targetUrl = url.searchParams.get('url') // 例如 ?url=https://webapi.115.com/...
if (!targetUrl) {
return new Response('Missing url param', { status: 400 })
}
// 3. 发起请求给 115 (Server-to-Server)
// 注意:这里伪造了 User-Agent 和 Cookie,绕过 115 的校验
const resp = await fetch(targetUrl, {
headers: {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
Cookie: COOKIE
}
})
// 4. 把 115 的返回结果直接透传给前端
const data = await resp.json()
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
})
}API 深度解析
onRequest(context): 这是 Pages Functions 的标准入口函数。context.env: 这是一个包含所有环境变量的对象。- 本地开发时:它加载
.dev.vars文件中的内容。 - 线上部署时:它加载 Cloudflare Dashboard 中设置的 Environment Variables (Secrets)。
- 本地开发时:它加载
context.request: 一个标准的 Web APIRequest对象,包含了前端发来的所有信息(URL、Method、Headers)。
敏感信息管理 (Cookie)
严禁将 Cookie 硬编码在代码中提交到 GitHub。
- 线上环境: 使用 Wrangler 命令上传加密存储:
npx wrangler secret put COOKIE_115
# 终端会提示你输入具体的值,输入过程不可见- 本地环境: 详见 5.4 节。
图片代理服务 (防盗链处理)
115 的图片服务器有防盗链检查,如果请求头中的 Referer 不是 115.com,图片将无法加载(显示 403 Forbidden)。我们需要一个代理来“清洗”请求头。
后端代码实现
请在 functions/api/img-proxy.js 中写入以下代码:
export async function onRequest(context) {
const COOKIE = context.env.COOKIE_115
const url = new URL(context.request.url)
const targetUrl = url.searchParams.get('url')
if (!targetUrl) return new Response('Missing URL', { status: 400 })
// 发起请求,核心在于伪造 Referer
const resp = await fetch(targetUrl, {
headers: {
Cookie: COOKIE,
Referer: 'https://115.com/' // 关键:骗过防盗链检查
}
})
// 直接返回图片流 (Stream),实现零内存开销
// 不要使用 await resp.blob(),那会消耗大量内存
return new Response(resp.body, {
headers: {
// 转发原始图片的 Content-Type (如 image/jpeg)
'Content-Type': resp.headers.get('Content-Type') || 'image/jpeg'
}
})
}前端调用示例
在 Vue 组件中,你不能直接写 <img src="https://115.com/img/..." />。 你需要写:
<img src="/api/img-proxy?url=https://115.com/img/..." />这样请求会先发给你的 Worker,Worker 加上 Referer: https://115.com/ 后再去请求 115,从而成功拿到图片。
本地全栈开发环境
为了在本地同时运行 Vue 前端和 Functions 后端,并让它们能够通信,我们需要配置 Wrangler 代理。
配置本地环境变量
Wrangler 在本地运行时不会去读取线上的 Secrets。你必须在项目根目录创建一个 .dev.vars 文件。
文件内容 (.dev.vars):
COOKIE_115=UID=12345;CID=abcde;SEID=...注意: 等号周围不要有空格。此文件包含敏感信息,请务必加入
.gitignore。
修改启动脚本
普通的 npm run dev 只能启动 Vue,无法运行 functions/ 目录下的后端代码。我们需要修改 package.json 的 scripts 字段。
修改前:
"scripts": {
"dev": "vite",
"build": "vite build"
}修改后:
"scripts": {
"dev": "vite",
"build": "vite build",
"pages:dev": "wrangler pages dev -- proxy 5173"
}运行与调试
在终端运行以下命令启动开发环境:
npm run pages:dev运行原理解析:
启动 Wrangler: 命令会启动 Wrangler 的本地服务器(通常在
http://localhost:8788)。启动 Vite: Wrangler 会自动运行
npm run dev(启动 Vite 服务器,端口 5173)。请求代理 (Proxy):
当你访问
http://localhost:8788/api/115时 -> Wrangler 拦截请求 -> 执行functions/api/115.js-> 返回结果。当你访问
http://localhost:8788/assets/logo.png时 -> Wrangler 发现这不是 API -> 将请求转发给 Vite (端口 5173) -> 返回静态资源。
重要提示: 在浏览器中开发时,请务必访问
http://localhost:8788,而不是 Vite 的 5173 端口,否则你的 API 请求会失败(404 或跨域)。